{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 使用梯度上升法求解主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.empty((100,2))\n",
    "X[:,0] = np.random.uniform(0., 100., size=100)\n",
    "# 生成X的第1个特征为第0个特征的某种线性关系再加点噪音\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1064dde80>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:,0], X[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## demean操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    \"\"\"\n",
    "    所有样本减去均值\n",
    "    :param X: \n",
    "    :return: \n",
    "    \"\"\"\n",
    "    return X - np.mean(X, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_demean = demean(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x104971978>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0], X_demean[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  2.03925765e-14,  -7.03437308e-15])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X_demean, axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，demean之后，均值非常接近0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    \"\"\"\n",
    "    效用函数\n",
    "    :param w: \n",
    "    :param X:   demean后的X \n",
    "    :return: \n",
    "    \"\"\"\n",
    "    return np.sum((X.dot(w))**2) / len(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_math(w,X):\n",
    "    \"\"\"\n",
    "    给定w，X，求梯度\n",
    "    :param w: \n",
    "    :param X: demean后的X\n",
    "    :return: \n",
    "    \"\"\"\n",
    "    return X.T.dot(X.dot(w)) * 2. / len(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 验证一下这个梯度函数是否正确"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_debug(w, X, epsilon=0.0001):\n",
    "    res = np.empty(len(w))\n",
    "    for i in range(len(w)):\n",
    "        w_1 = w.copy()\n",
    "        w_1[i] += epsilon\n",
    "        w_2 = w.copy()\n",
    "        w_2[i] -= epsilon\n",
    "        res[i] = (f(w_1,X) - f(w_2,X)) / (2*epsilon)\n",
    "    return res\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def gradient_ascent(df, X, initial_w, eta, n_iters=1e4, epsilon=1e-8):\n",
    "    w = direction(initial_w)\n",
    "    cur_iter = 0\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w,X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w)    # 注意1： 每次求一个单位方向\n",
    "        if (abs(f(w,X) - f(last_w, X)) < epsilon):\n",
    "            break\n",
    "        cur_iter += 1\n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.36141063,  0.13370123])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 初始值不可以是0向量 ！\n",
    "initial_w = np.random.random(X.shape[1])\n",
    "initial_w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "eta = 0.001"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 注意，不能使用Standard Scaler标准化数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 2.21 ms, sys: 2 ms, total: 4.21 ms\nWall time: 2.51 ms\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ 0.78614633,  0.61804042])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time gradient_ascent(df_debug, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 849 µs, sys: 13 µs, total: 862 µs\nWall time: 871 µs\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ 0.78614633,  0.61804042])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time gradient_ascent(df_math, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 把这条轴画出来看看"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10655d470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "w = gradient_ascent(df_math, X_demean, initial_w, eta)\n",
    "\n",
    "plt.scatter(X_demean[:,0], X_demean[:,1])\n",
    "plt.plot([0, w[0]*30], [0, w[1]*30], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 一种极端的情况？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "X2 = np.empty((100,2))\n",
    "X2[:,0] = np.random.uniform(0., 100., size=100)\n",
    "# 生成X的第1个特征为第0个特征的某种线性关系再加点噪音\n",
    "X2[:,1] = 0.75 * X2[:,0] + 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXUAAAD8CAYAAACINTRsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAGh9JREFUeJzt3X+M3HWdx/Hnu8OiW7xzqaxNWdhrVVKDVlqzkTU1RkGuiAprwxWxeM1dY+8Pz0PlqsVrDkzQ1vQUueRCUkGtZ68UsA71R+x5BWOOSM/WLSy/9qAcFIZCV+mqp5tzad/3x3y/ZXY6P76zM9+Z73y/r0fS7MzsjPMZBl98+v6+P5+PuTsiIpIOczo9ABERaR2FuohIiijURURSRKEuIpIiCnURkRRRqIuIpIhCXUQkRRTqIiIpolAXEUmR09r5ZmeddZYvXLiwnW8pItL1Dhw48Ct374/y3LaG+sKFC9m/f38731JEpOuZ2TNRn6vyi4hIiijURURSRKEuIpIiCnURkRRRqIuIpEhbu19ERLIkP1pgy55xnp+c4uy+XtavWMzIsoFY31OhLiISg435MbY/cJjwbLnC5BTX7xoDiDXYVX4REWmx/GhhRqCHpqaPs2XPeKzvrVAXEWmxLXvGTwn00POTU7G+t0JdRKTFagX32X29sb63Ql1EpMWqBbcB61csjvW9FeoiIi22fsVientyMx4zYPXwoLpfRESSJEqbYni/3e2MoFAXEYksP1rg+l1jTE0fB2q3KY4sG2hLiJdT+UVEJKIte8ZPBnqoHW2KjdBMXUSkhtJyS6faFBuhUBcRqaK83FJN3G2KjVCoi4hUkB8tcN2dD3Lcq83Pi3p7crG3KTZCoS4iUiacodcKdIO2drVEpVAXESlT6YJoqYG+Xu7fcFEbRxRd3VA3s8XAzpKH3gD8I/Dt4PGFwNPAKnc/1vohiojEq7z3vFDjwmfSyi3l6oa6u48DSwHMLAcUgO8BG4C97r7ZzDYE9z8X41hFRFomDPLC5BQGM7bILb1fKmfGppVLElVuKddon/rFwCF3fwa4AtgWPL4NGGnlwERE4hLWzMMZeXmAO8WaeanenhxfWXVBogMdGg/1jwA7gtvz3f1IcPsFYH6lF5jZOjPbb2b7JyYmZjlMEZHWqVczh2KwD/T1YsHPpM/QQ5EvlJrZ6cDlwPXlv3N3N7OKl4ndfSuwFWBoaKh2b5CISIxKSy71JPliaC2NdL+8H/ilu78Y3H/RzBa4+xEzWwAcbf3wRERaI+pCIkj+xdBaGim/XM0rpReA3cCa4PYa4J5WDUpEpNXqlVzCGno3lVoqiTRTN7MzgEuAvyl5eDNwp5mtBZ4BVrV+eCIirVFrf5aBBC4imq1Ioe7uvwdeV/bYryl2w4iIJF61/vNurZ1Xo613RSQ18qMFlm++l0UbfsjyzfeSHy2c/F2l04i6uXZejbYJEJFUqHeARSdPI2onhbqIpEKtAyzC4O7UaUTtpFAXka7VbQdYtINCXUS6SrU9W6pJ0gEW7aBQF5GuUV43rxfoabwQWo9CXUS6RpQ9WyC5B1i0g0JdRBJtY36MHfuerXusXChtfeeNUqiLSCLlRwusv+sg0yeivyaL5ZZyCnURSZyN+TG+88DhSM8NL5amaal/MxTqIpIYG/NjbN93mCiVlizXzWtRqItIIlzy1Z/yxNHfR3puzoxDmy6LeUTdSXu/iEjHbcyPRQ50gKsvPDfG0XQ3hbqIdNyOfc9Gfu7yN87jppElMY6mu6n8IiIdF6Vd8YzTc3zxw917eEW7KNRFpG3yowVu3P0Ik1PTAJw5t4cbPvQWcmZVg31uzxy+tPJtCvOIFOoi0hbFvvMHmT7xSngf+8M06+9+kOE3nMn9h1465TXnvf4MfvKZ97RxlN1PNXURaYste8ZnBHpo+rjz9K+nuGZ4kJwVTwrNmXHN8KACfRainlHaB9wGvJVin/9fA+PATmAh8DSwyt2PxTJKEel6tbbAfX5yiptGlugCaAtELb/cAvzY3a80s9OBucDngb3uvtnMNgAbgM/FNE4R6SKl+5yHC4SqnREK2dseN051yy9m9lrg3cDtAO7+R3efBK4AtgVP2waMxDVIEeke4fa4heDgivBYufe+uZ+eOXbK83tylvn9Wlopykx9ETABfNPMLgAOANcC8939SPCcF4D58QxRRLpBrd0Up6aPc9/jE2z5iwsqdr+os6V1ooT6acDbgU+6+z4zu4ViqeUkd3czq9iPZGbrgHUAg4ODTQ5XRJIoygZcz09OZeKM0E6L0v3yHPCcu+8L7t9NMeRfNLMFAMHPo5Ve7O5b3X3I3Yf6+/tbMWYRSZgoK0JVN2+PujN1d3/BzJ41s8XuPg5cDDwa/FkDbA5+3hPrSEUkUaIc+hzSPuftE7X75ZPA9qDz5SngryjO8u80s7XAM8CqeIYoIklTflZoLdrnvL0ihbq7HwSGKvzq4tYOR0S6QdSzQq8ZHlTveZtpmwARaVithURQXBF69YXnKtA7QKEuIlVVWkQ0smyg6kKirB/6nAQKdRGpaGN+jO0PHD55ETRcRASwfsXiU2rquhiaDNrQS0ROEfadl3e1TE0fZ8uecUaWDbBp5RIG+noxijP0TSu113kSaKYuIjPkRwtsr7GQKKynayFRMmmmLiIzbNkzXrPvXIuIkk0zdZGMK78YWm0nRQAD1c0TTqEukmHli4gKk1MYVJ2prx4eVMkl4VR+EcmwSouInOKMvJShhUTdQjN1kQyJWmpxih0t5f3pknwKdZGMaKTUokVE3UuhLpJy+dHCjIMpSoWlltJg1yKi7qaaukiK5UcLrL/rwYqBHgpLLVpElA6aqYuk2JY940yfqL3buUot6aJQF0mRWqWWSlRqSR+FukhK5EcLfGbnQU5EfH7OTKWWFFJNXSQlbtz9SORA78kZX1l1gQI9hTRTF0mJqCWXM+f2cMOH3qJAT6lIoW5mTwO/A44DL7v7kJnNA3YCC4GngVXufiyeYYpIM3QxNDsaKb+8192Xunt4VukGYK+7nwfsDe6LSMzyowWWb76XRRt+yPLN95IfLQDFGXg1uhiaHc3U1K8AtgW3twEjzQ9HRGoJV4UWJqdwXjmNKD9a4IYPvYWeXPmuLcU9W1RqyY6ooe7Av5vZATNbFzw2392PBLdfAOa3fHQiMkOlDbhKTyPacuUFMxYSfe2qpdqEK2OiXih9l7sXzOz1wE/M7PHSX7q7m1nFFQ7BfwTWAQwODjY1WJGsiboBl04jklCkUHf3QvDzqJl9D3gH8KKZLXD3I2a2ADha5bVbga0AQ0NDtZe2ichJlQ5+rrYBl04jklDd8ouZnWFmfxLeBv4ceBjYDawJnrYGuCeuQYpkTXhOaHmAV9rrXKtCpVSUmfp84HtmFj7/39z9x2b2C+BOM1sLPAOsim+YItlS65xQ7XUutdQNdXd/CrigwuO/Bi6OY1AiWfd8jXNC1XMutWhFqUgHlV8IDWfd1S6K6uBnqUehLtIhlS6EXr9rDCgGd+kpRVAMdB38LPUo1EU6oNqF0LDnPCyvVJrFi9SiUBdpoyj7navnXJqhUBdpk/BouXonEannXJqh/dRF2iTK0XK6ECrNUqiLtEmtNkXQhVBpDZVfRNqk1t4tOdNJRNIamqmLtFi1/c7Xr1hMz5xTt8bV0XLSSpqpi7RQuN952F9e2nsehnZp94uOlpNWU6iLNKl0VegcM477zIuhpfudq01R4qZQF2lC+cy8PNBD9S6SirSKauoiTah0ElEl6j2XdtFMXaQB+dECn9/1EH+YPhH5NdrvXNpJoS4S0cb8GN954HCk5+bMOOGuPVuk7RTqInUUl/cfJOrkvLcnx6aVSxTk0hEKdZEa8qMFPrPzIFHy3EAzc+k4hbpIFfnRAtfd+WCkQM+ZcWjTZbGPSaSeyN0vZpYzs1Ez+0Fwf5GZ7TOzJ81sp5mdHt8wRdorbFWs1qJY7uoLz415RCLRNNLSeC3wWMn9LwM3u/ubgGPA2lYOTKSTorYqGnDN8CA3jSyJf1AiEUQqv5jZOcAHgC8CnzEzAy4CPho8ZRtwI3BrDGMUiVWlc0KjLBZa/sZ5bP/4O9swQpHoos7UvwZ8Fk6WF18HTLr7y8H95wBdGZKuE5ZZCpNTOK/s1dI3t6fqa+ZYcXauQJckqjtTN7MPAkfd/YCZvafRNzCzdcA6gMHBwYYHKBKX8EJopb1aXnXaHHp7cjNKMGpVlG4QpfyyHLjczC4DXg38KXAL0GdmpwWz9XOAQqUXu/tWYCvA0NBQtKtOIjGKck7ob6amufmqpTr4WbpO3VB39+uB6wGCmfrfu/tqM7sLuBK4A1gD3BPjOEVaonwDrmrO7uvVjorSlZrpU/8ccIeZ3QSMAre3ZkgirRdeDK128lAp7dUi3ayhUHf3nwI/DW4/Bbyj9UMSaa2N+TG2P3CYKLW/nJnq5tLVtKJUUilK3bycLoRKGijUJXUa2U0xpGPlJC0U6pIqjQb6gLpaJGUU6pIajQS6ATdftVRhLqmj4+wkFfKjBbY3EOirhwcV6JJKmqlLKmzZMx6pu6Wvt4cbL1ftXNJLoS5dqXwTrij959pNUbJAoS5dp3xVaGFyCoOqM/UzTs/xxQ+rVVGyQaEuXWNjfowd+56teHCFwynBHtbONTuXLFGoS1dY/fWfc/+hl2o+xym2KGoDLskyhbokVn60wBe+/wjH/hBtVehAXy/3b7go5lGJJJtCXRKp0UVE2oRLpEihLonTSM85aFWoSCmFuiRO1J5zUJuiSDmFuiRCad951EBf/sZ5CnSRMgp16biopxGFtKOiSHUKdem4LXvGIwX63J45fGnl2xTmIjUo1KXjnq+xxN9APeciDVCoS9uUrgjNmXH1hedy08iSqnu3qO9cpHF1Q93MXg38DHhV8Py73f0GM1sE3AG8DjgAfMzd/xjnYKU7FWvmDzE1feLkY8fdT/ahr1+x+JSauvrORWYnyn7q/wdc5O4XAEuBS81sGPgycLO7vwk4BqyNb5jSrfKjBdbf/eCMQC+1Y9+zjCwbYNPKJQz09WIUZ+g6K1RkdurO1N3dgf8N7vYEfxy4CPho8Pg24Ebg1tYPUbrZF77/CNPHqzcphptzjSwbUIiLtECkk4/MLGdmB4GjwE+AQ8Cku78cPOU5oOL/I81snZntN7P9ExMTrRizdJF6+7bkzNo0EpFsiBTq7n7c3ZcC5wDvAN4c9Q3cfau7D7n7UH9//yyHKWl19YXndnoIIqnSUPeLu0+a2X3AO4E+MzstmK2fAxTiGKAkX/luiqVHxvX19jA5VXm2riX+Iq1Xd6ZuZv1m1hfc7gUuAR4D7gOuDJ62BrgnrkFKcuVHC1x314MzyiyTU9Osv+tB8qMFbrz8LfTMmVli6ZljfO2qpQp0kRhEmakvALaZWY7ifwTudPcfmNmjwB1mdhMwCtwe4zglYcK9WqqdDTp9wtmyZ/xkn3npeaJaSCQSnyjdLw8Byyo8/hTF+rpkTNS9WsKVoupsEWmfSBdKRUpF3avl7L7eNoxGREop1KVhtfZqKaUVoSLtp1CXhkWZgV8zPKiSi0gHKNSlYetXLKa3JzfjsbC/ZaCvV50tIh2kXRqlYeEMXB0tIsmjUJdZUUeLSDIp1AWYeUaoZt4i3UuhLmzMj7H9gcMnD3wuTE5x/a4xAAW7SJfRhdKMW/31n/OdkkAPTU0fZ8ue8Y6MSURmT6GeYRvzY9x/6KWqv4/ajy4iyaFQz7Ad+56t+XutCBXpPqqpZ0Sl7XHDU4cqMbQiVKQbKdQzIDwntPRYuWp7nIdWa0WoSFdS+SUDtuwZr3lOaLnlb5ynFaEiXUqhngH1LniG54TmzLhmeJDtH39nO4YlIjFQ+SUDzu7rrXqYxUBf78mDLESk+2mmngHrVyymJ2enPN4zx3QxVCRlNFNPiVrL/MOf1Q6HFpH0qBvqZnYu8G1gPuDAVne/xczmATuBhcDTwCp3PxbfUKWa8uPlKi3z1wZcItkQpfzyMnCdu58PDAOfMLPzgQ3AXnc/D9gb3JcOqHS8nJb5i2RT3VB39yPu/svg9u+Ax4AB4ApgW/C0bcBIXIOU2qp1t2iZv0j2NHSh1MwWAsuAfcB8dz8S/OoFiuUZ6YBqy/m1zF8keyKHupm9Bvgu8Cl3/23p79zd4ZSN/sLXrTOz/Wa2f2JioqnBZll+tMDyzfeyaMMPWb75XvKjhZO/q3S8XG9PTp0tIhkUKdTNrIdioG93913Bwy+a2YLg9wuAo5Ve6+5b3X3I3Yf6+/tbMebMCS+EFiancF65EBoG+8iyATatXMJAXy9Gsfd808olujAqkkFRul8MuB14zN2/WvKr3cAaYHPw855YRig1L4Squ0VESkXpU18OfAwYM7ODwWOfpxjmd5rZWuAZYFU8Q8ye8p7zaqtBdSFURMrVDXV3/0+KO7FWcnFrhyOVes6NyhcsdCFURMppm4CEqVRqcU79r6ouhIpIJQr1hKlWUnHQhVARqUt7v3RQpf1aqtXQtZuiiEShmXqHbMyP8emdB09pU3zvm/vVcy4is6ZQ74CN+TG+88DhUy5+Tk0f577HJ9RzLiKzpvJLG5Uf/lzJ85NT6jkXkVlTqLdJeatiNWpTFJFmqPzSJpVaFcsZqHYuIk1RqLdJlNWfq4cHVXYRkaao/BKDRloVoThDXz08yE0jS9o7UBFJHc3UW6zajoqVWhWheFbozVctVaCLSEtopt4CpTPzOWYc95nNiqWtitUOhxYRaQWFepPKu1rKAz2kVkURaQeVX5oUpasF1KooIu2hUG9SlK4WLfMXkXZRqDep2gw8Z6Zl/iLSdqqpN2n9isWnrBTt7ckpyEWkIxTqTQqDW10tIpIEUQ6e/gbwQeCou781eGwesBNYCDwNrHL3Y/ENM9nU1SIiSRGlpv4t4NKyxzYAe939PGBvcF9ERDqsbqi7+8+Al8oevgLYFtzeBoy0eFwiIjILs62pz3f3I8HtF4D5LRpPx1Tar0UlFRHpNk1fKHV3N7PKyygBM1sHrAMYHBxs9u1iUb4qNNyvBVCwi0hXmW2f+otmtgAg+Hm02hPdfau7D7n7UH9//yzfLl6VVoVOTR9ny57xDo1IRGR2Zhvqu4E1we01wD2tGU5nVFsVGmW1qIhIktQNdTPbAfwcWGxmz5nZWmAzcImZPQG8L7jftaqtCtV+LSLSberW1N396iq/urjFY+mYaqtCtV+LiHQbrShFq0JFJD1SH+pRWxW1KlRE0iDVoa5WRRHJmlRvvatWRRHJmlSHuloVRSRrUh3qalUUkaxJdaivX7GY3p7cjMfUqigiadbVF0rrdbaoVVFEsqYrQz0/WuDG3Y8wOTV98rFqnS1qVRSRLOm68kvYplga6CF1tohI1nVdqFdqUyylzhYRybLEl1/K6+aFOqGtzhYRybJEh3qlFaEGVDuRQ50tIpJ1iS6/VCq1OGAVnnvm3B42rVyii6IikmmJnqlXq487MNDXqzZFEZEyiQ71ajX0gb5e7t9wUQdGJCKSbIkuv2hFqIhIYxI9U9eKUBGRxjQV6mZ2KXALkANuc/eWn1WqFaEiItHNuvxiZjngX4D3A+cDV5vZ+a0amIiINK6Zmvo7gCfd/Sl3/yNwB3BFa4YlIiKz0UyoDwDPltx/LnhMREQ6JPbuFzNbZ2b7zWz/xMRE3G8nIpJpzYR6ATi35P45wWMzuPtWdx9y96H+/v4m3k5EROox92o7qdR5odlpwH8DF1MM818AH3X3R2q8ZgJ4ZlZvCGcBv5rla7udPns26bNnU6XP/mfuHmlWPOuWRnd/2cz+FthDsaXxG7UCPXjNrKfqZrbf3Ydm+/pups+uz541+uyz/+xN9am7+4+AHzXzvyEiIq2T6G0CRESkMd0U6ls7PYAO0mfPJn32bGrqs8/6QqmIiCRPN83URUSkjsSHupldambjZvakmW3o9HjiZGbnmtl9ZvaomT1iZtcGj88zs5+Y2RPBzzM7Pda4mFnOzEbN7AfB/UVmti/4/nea2emdHmMczKzPzO42s8fN7DEze2dWvncz+3Tw7/vDZrbDzF6d1u/dzL5hZkfN7OGSxyp+z1b0z8E/g4fM7O1R3iPRoZ7BTcNeBq5z9/OBYeATwefdAOx19/OAvcH9tLoWeKzk/peBm939TcAxYG1HRhW/W4Afu/ubgQso/jNI/fduZgPA3wFD7v5Wiu3RHyG93/u3gEvLHqv2Pb8fOC/4sw64NcobJDrUydimYe5+xN1/Gdz+HcX/Yw9Q/MzbgqdtA0Y6M8J4mdk5wAeA24L7BlwE3B08JZWf3cxeC7wbuB3A3f/o7pNk5Hun2FrdGyxonAscIaXfu7v/DHip7OFq3/MVwLe96AGgz8wW1HuPpId6ZjcNM7OFwDJgHzDf3Y8Ev3oBmN+hYcXta8BngRPB/dcBk+7+cnA/rd//ImAC+GZQerrNzM4gA9+7uxeAfwIOUwzz3wAHyMb3Hqr2Pc8q/5Ie6plkZq8Bvgt8yt1/W/o7L7Yrpa5lycw+CBx19wOdHksHnAa8HbjV3ZcBv6es1JLi7/1MijPSRcDZwBmcWp7IjFZ8z0kP9UibhqWJmfVQDPTt7r4rePjF8K9dwc+jnRpfjJYDl5vZ0xTLbBdRrDP3BX8th/R+/88Bz7n7vuD+3RRDPgvf+/uA/3H3CXefBnZR/HchC997qNr3PKv8S3qo/wI4L7gSfjrFCyi7Ozym2AQ15NuBx9z9qyW/2g2sCW6vAe5p99ji5u7Xu/s57r6Q4vd8r7uvBu4DrgyeltbP/gLwrJmFJ6pfDDxKBr53imWXYTObG/z7H3721H/vJap9z7uBvwy6YIaB35SUaapz90T/AS6juBvkIeAfOj2emD/ruyj+1esh4GDw5zKKteW9wBPAfwDzOj3WmP85vAf4QXD7DcB/AU8CdwGv6vT4YvrMS4H9wXefB87MyvcOfAF4HHgY+FfgVWn93oEdFK8dTFP8G9raat8zYBS7/w4BYxQ7hOq+h1aUioikSNLLLyIi0gCFuohIiijURURSRKEuIpIiCnURkRRRqIuIpIhCXUQkRRTqIiIp8v/jHepr9b5v+QAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10680c828>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "X2_demean = demean(X2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.80000059,  0.59999922])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient_ascent(df_math, X2_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "w向量就是(0.8,0.6)这个点，这个点与原点之间的连线，斜率刚好是0.75，结果正确"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "w2 = gradient_ascent(df_math, X2_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x106811390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2_demean[:,0], X2_demean[:,1])\n",
    "plt.plot([0, w2[0]*30], [0, w2[1]*30], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
